package com.puzzle;

import com.common.GameBoard;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.filechooser.FileNameExtensionFilter;

// 主窗口
@SuppressWarnings("serial")
class MainWindow extends JFrame implements ActionListener, Game.Callback {
    private Game mGame;                                 // 游戏
    private JRadioButtonMenuItem mMenuItemEasy;         // "简单"菜单项
    private JRadioButtonMenuItem mMenuItemHard;         // "困难"菜单项
    private JRadioButtonMenuItem mMenuItemHasBorder;    // "有"菜单项
    private JRadioButtonMenuItem mMenuItemMedium;       // "中等"菜单项
    private JRadioButtonMenuItem mMenuItemNoBorder;     // "无"菜单项
    private JMenuItem mMenuItemSetPicture;              // "换图片"菜单项
    private JMenuItem mMenuItemStart;                   // "开始"菜单项

    /**
     * 构造方法。
     */
    public MainWindow() {
        // 设置当单击右上角的X按钮时退出程序
        super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        
        // 设置窗口标题
        super.setTitle(Const.getString("IDS_APP_NAME"));
        
        // 设置窗口尺寸不能改变
        super.setResizable(false);
        
        // 设置窗口尺寸
        super.setSize(Const.WIDTH, Const.HEIGHT);
        
        // 设置窗口居中
        super.setLocationRelativeTo(null); 

        // 创建菜单
        this.createMenu();

        // 创建游戏区域
        final GameBoard gameBoard = new GameBoard(this, 0, 0, Const.GAME_BOARD_WIDTH, Const.GAME_BOARD_HEIGHT);

        // 创建游戏
        mGame = new Game(this, gameBoard.getDrawer(), gameBoard);
    }

    /**
     * 所有菜单项的单击响应方法。
     * @param e 事件相关信息
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        final Object source = e.getSource();
        if (source == mMenuItemStart) {
            this.onMenuItemStartClicked();
        } else if (source == mMenuItemHasBorder || source == mMenuItemNoBorder) {
            this.onMenuItemSetBorderClicked((JMenuItem)source);
        } else if (source == mMenuItemEasy || source == mMenuItemMedium || source == mMenuItemHard) {
            this.onMenuItemSetDifficultyClicked((JMenuItem)source);
        } else if (source == mMenuItemSetPicture) {
            this.onMenuItemSetPictureClicked();
        }
    }
    
    /**
     * 创建菜单。
     */
    private void createMenu() {
        // 创建菜单栏
        final JMenuBar mainMenuBar = new JMenuBar();
        super.setJMenuBar(mainMenuBar);

        // 创建"游戏"菜单
        final JMenu menuGame = new JMenu(Const.getString("IDS_GAME"));
        mainMenuBar.add(menuGame);
        
        // 创建"开始"菜单项
        mMenuItemStart = new JMenuItem(Const.getString("IDS_START"));
        menuGame.add(mMenuItemStart);
        mMenuItemStart.addActionListener(this);
        
        // 创建"设置"菜单
        final JMenu menuOption = new JMenu(Const.getString("IDS_OPTION"));
        mainMenuBar.add(menuOption);

        // 创建"难度"
        final JMenu menuDifficulty = new JMenu(Const.getString("IDS_SET_DIFFICULTY"));
        menuOption.add(menuDifficulty);
        
        // 创建"简单"菜单项
        mMenuItemEasy = new JRadioButtonMenuItem(Const.getString("IDS_EASY"));
        menuDifficulty.add(mMenuItemEasy);
        mMenuItemEasy.addActionListener(this);
        mMenuItemEasy.setSelected(true);
        
        // 创建"中等"菜单项
        mMenuItemMedium = new JRadioButtonMenuItem(Const.getString("IDS_MEDIUM"));
        menuDifficulty.add(mMenuItemMedium);
        mMenuItemMedium.addActionListener(this);
        
        // 创建"困难"菜单项
        mMenuItemHard = new JRadioButtonMenuItem(Const.getString("IDS_HARD"));
        menuDifficulty.add(mMenuItemHard);
        mMenuItemHard.addActionListener(this);

        // 创建"图片边框"菜单
        final JMenu menuBorder = new JMenu(Const.getString("IDS_SET_BORDER"));
        menuOption.add(menuBorder);
        
        // 创建"有"菜单项
        mMenuItemHasBorder = new JRadioButtonMenuItem(Const.getString("IDS_HAS_BORDER"));
        menuBorder.add(mMenuItemHasBorder);
        mMenuItemHasBorder.addActionListener(this);
        mMenuItemHasBorder.setSelected(true);
        
        // 创建"无"菜单项
        mMenuItemNoBorder = new JRadioButtonMenuItem(Const.getString("IDS_NO_BORDER"));
        menuBorder.add(mMenuItemNoBorder);
        mMenuItemNoBorder.addActionListener(this);
        
        // 创建"换图片"菜单项
        mMenuItemSetPicture = new JMenuItem(Const.getString("IDS_SET_PCITURE"));
        menuOption.add(mMenuItemSetPicture);
        mMenuItemSetPicture.addActionListener(this);        
    }

    /**
     * 游戏结束事件的响应方法。
     */
    @Override
    public void onGameOver() {
        // 显示胜利提示信息
        final String text = Const.getString("IDS_WON");
        JOptionPane.showMessageDialog(this, text, " ", JOptionPane.INFORMATION_MESSAGE);
    }

    /**
     * "图片边框"菜单项的单击响应方法。
     * @param menuItem  用户单击的菜单项
     */
    private void onMenuItemSetBorderClicked(JMenuItem menuItem) {
        // 如果要设置的参数与当前游戏参数相同，则直接返回
        final boolean hasBorder = menuItem == mMenuItemHasBorder;
        if (hasBorder == mGame.pictureHasBorder()) {
            menuItem.setSelected(true);
            return;
        }

        // 设置边框
        mGame.setPictureHasBorder(hasBorder);

        // 选中菜单项
        mMenuItemHasBorder.setSelected(hasBorder);
        mMenuItemNoBorder.setSelected(!hasBorder);
    }

    /**
     * "难度"菜单项的单击响应方法。
     * @param menuItem  用户单击的菜单项
     */
    private void onMenuItemSetDifficultyClicked(JMenuItem menuItem) {
        // 如果要设置的参数与当前游戏参数相同，则直接返回
        Game.Difficulty newDiff = Game.Difficulty.EASY;
        if (menuItem == mMenuItemMedium) {
            newDiff = Game.Difficulty.MEDIUM;
        } else if (menuItem == mMenuItemHard) {
            newDiff = Game.Difficulty.HARD;
        }
        if (newDiff == mGame.getDifficulty()) {
            menuItem.setSelected(true);
            return;
        }
        
        // 弹出询问对话框
        if (mGame.getStatus() != Game.Status.END) {
            final int clickedButton = JOptionPane.showConfirmDialog(this, 
                Const.getString("IDS_RESET"), " ", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
            if (clickedButton == JOptionPane.NO_OPTION) {
                menuItem.setSelected(false);
                return;
            }
        }

        // 设置难度
        mGame.setDifficulty(newDiff);

        // 选中菜单项
        mMenuItemEasy.setSelected(false);
        mMenuItemMedium.setSelected(false);
        mMenuItemHard.setSelected(false);
        menuItem.setSelected(true);
    }

    /**
     * "换图片"菜单项的单击响应方法。
     */
    private void onMenuItemSetPictureClicked() {
        // 弹出询问对话框
        int clickedButton;
        if (mGame.getStatus() != Game.Status.END) {
            clickedButton = JOptionPane.showConfirmDialog(this, 
                Const.getString("IDS_RESET"), " ", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
            if (clickedButton == JOptionPane.NO_OPTION) {
                return;
            }
        }

        // 弹出选择图片对话框
        final JFileChooser fileDlg = new JFileChooser();
        final FileNameExtensionFilter fnef = new FileNameExtensionFilter("(*.bmp; *.gif; *.jpg; *.png)", "bmp", "gif", "jpg", "png");
        fileDlg.setFileFilter(fnef);
        clickedButton = fileDlg.showOpenDialog(this);
        if (clickedButton != JFileChooser.APPROVE_OPTION) {
            return;
        }

        // 设置图片
        mGame.setPicture(fileDlg.getSelectedFile());
    }

    /**
     * "开始"菜单项的单击响应方法。
     */
    private void onMenuItemStartClicked() {
        mGame.start();
    }
}
